package com.irdstudio.efp.nls.service.impl.loan_repay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.irdstudio.basic.framework.core.constant.BaseConstant;
import com.irdstudio.basic.framework.core.exception.ESBException;
import com.irdstudio.efp.basic.framework.mq.client.producer.MQProducerMessageClient;
import com.irdstudio.efp.basic.framework.mq.constant.TagEnums;
import com.irdstudio.efp.basic.framework.mq.constant.TopicEnums;
import com.irdstudio.efp.esb.service.bo.resp.sed.repay.RespLoanRepayResultQryBean;
import com.irdstudio.efp.limit.service.facade.LmtPrdContService;
import com.irdstudio.efp.limit.service.vo.LmtPrdContVO;
import com.irdstudio.efp.nls.common.constant.sed.SedNlsEnum;
import com.irdstudio.efp.nls.service.facade.NlsApplyInfoService;
import com.irdstudio.efp.nls.service.impl.LoanReleaseOrRepayQueueHangHandle;
import com.irdstudio.efp.nls.service.impl.psd.apply.PsdLoanReleaseServiceImpl;
import com.irdstudio.efp.nls.service.impl.psd.apply.PsdSyncLoanInfoServiceImpl;
import com.irdstudio.efp.nls.service.impl.yed.apply.YedLoanReleaseServiceImpl;
import com.irdstudio.efp.nls.service.impl.yed.apply.YedSyncLoanInfoServiceImpl;
import com.irdstudio.efp.nls.service.vo.NlsApplyInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.Optional;

import static com.irdstudio.basic.framework.core.constant.BaseConstant.NLS_APPLY_STATE_03;
import static com.irdstudio.efp.nls.common.constant.psd.NlsApplyFlowStatus.*;
import static com.irdstudio.efp.nls.common.constant.sed.DealState.*;
import static com.irdstudio.efp.nls.common.constant.sed.DealState.*;

/**
 * 需求编号:2019D08--
 * 问题编号:
 * 开发人员: caoxin
 * 创建日期:2019/11/6
 * 功能描述:
 * 修改日期:2019/11/6
 * 修改描述:
 */
@Service("loanReleaseCompensationTask")
public class LoanReleaseCompensationTask extends CompensationTask<NlsApplyInfoVO> {

    private static Logger logger = LoggerFactory.getLogger(LoanReleaseCompensationTask.class);
    @Override
    protected void updateStatus(NlsApplyInfoVO nlsApplyInfoVO) throws Exception {
        // 调用调款还款接口 查询互金该笔流水下的放款是否已经完成
        RespLoanRepayResultQryBean respLoanRepayResultQryBean = psdLoanReleaseService.getRespLoanRepayResultQryBean(nlsApplyInfoVO.getGlobalSerno());

        // 放款查询成功的 贷款号，发放号
        RespLoanRepayResultQryBean.TxnRsltInfBean txnRsltInfBean = Optional.
                ofNullable(respLoanRepayResultQryBean.parseTxnRsltInf()).
                orElseGet(RespLoanRepayResultQryBean.TxnRsltInfBean::new);

        // 放款状态判断 1：待处理 2：处理中 3：成功 4：失败 5：未知
        String txnStCd = respLoanRepayResultQryBean.getTxnStCd();

        // 218一共执行时间为 为16.6天 执行失败就更新比用信为失败 caoxin:这里可以使用配置化参数
        if (nlsApplyInfoVO.getExecuteTime() + 1 == 218) {
            NlsApplyInfoVO updateNlsApplyInfo =
                    updateNlsApplyInfoFailureStatus(nlsApplyInfoVO,
                            txnRsltInfBean.getBaseAcctNo(),
                            txnRsltInfBean.getAcctSeqNo());

            nlsApplyInfoService.updateByPk(updateNlsApplyInfo);
            return;
        }
        // 是否放款过
        String qrySt = respLoanRepayResultQryBean.getQrySt();
        NlsApplyInfoVO updateNlsApplyInfo = null;
        if (SUCCESS.getValue().equals(txnStCd)) { // 成功
            // 更新额度有效期为1年
            psdLoanReleaseService.updateLmtTerm(nlsApplyInfoVO);
            // 更新用信申请审批状态为成功,更新放款状态为放款成功
            updateNlsApplyInfo =
                    updateNlsApplyInfoSuccessStatus(nlsApplyInfoVO,
                            txnRsltInfBean.getBaseAcctNo(),
                            txnRsltInfBean.getAcctSeqNo());
            // 调用同步任务
            try {
                syncLoanInfoHsdService.doExecute(null, nlsApplyInfoVO);
            } catch (Exception e) {
                logger.info("用信申请流水号【"+nlsApplyInfoVO.getApplySeq()+"】放款成功,执行同步失败 等待补偿任务补偿");
                nlsApplyInfoVO.setFlowStatus(FLOW_STATUS_8);
                nlsApplyInfoVO.setNlsApplyState(BaseConstant.NLS_APPLY_STATE_01);
            }
        } else if (FAIL.getValue().equals(txnStCd) || (SedNlsEnum.QuerySts.WITHOUT.getValue().equals(qrySt) && StringUtils.isEmpty(txnStCd))) {// 失败
            // 更新用信申请审批状态为失败,更新放款状态为失败
             updateNlsApplyInfo =
                    updateNlsApplyInfoFailureStatus(nlsApplyInfoVO,
                    txnRsltInfBean.getBaseAcctNo(),
                    txnRsltInfBean.getAcctSeqNo());
            // 额度恢复
            // 获取额度信息
            LmtPrdContVO lmtPrdContVO = lmtPrdContService.qryLmtPrdContByLmtApplySeq(nlsApplyInfoVO.getLmtApplySeq());
            psdLoanReleaseService.recoverAmt(nlsApplyInfoVO,lmtPrdContVO);
        } else if (DEALING.getValue().equals(txnStCd) ||// 处理中
                SUSPEND.getValue().equals(txnStCd) ||// 待处理
                UNKNOW.getValue().equals(txnStCd)) { // 未知
            logger.info("用信申请流水号【"+nlsApplyInfoVO.getApplySeq()+"】 放款补偿任务正在执行 当前执行的次数为【"+nlsApplyInfoVO.getExecuteTime()+"】");
            logger.info("用信申请流水号【"+nlsApplyInfoVO.getApplySeq()+"】 用信申请为"+JSONObject.toJSONString(nlsApplyInfoVO));
            throw new ESBException("放款补偿任务执行");
        }

        nlsApplyInfoService.updateByPk(updateNlsApplyInfo);
    }

    @Override
    protected void sendMessage(NlsApplyInfoVO nlsApplyInfoVO) {
        try {

            int executeTime = nlsApplyInfoVO.getExecuteTime();

            nlsApplyInfoVO.setExecuteTime(++executeTime);
            nlsApplyInfoService.updateByPk(nlsApplyInfoVO);

            logger.info("用信申请流水号【" + nlsApplyInfoVO.getApplySeq() + "】 放款补偿任务正在执行 当前执行的次数为【" + nlsApplyInfoVO.getExecuteTime() + "】 延迟执行级别【" + delayLevel(nlsApplyInfoVO.getExecuteTime()) + "】");
            Message message = new Message(TopicEnums.LOANRELEASEORREPAY_QUEUE_TASK_TOPIC.getTopicId(), TagEnums.LOANRELEASEORREPAY_QUEUE_TASK.getTagId(),
                    nlsApplyInfoVO.getApplySeq().concat(".").concat(LoanReleaseOrRepayQueueHangHandle.NLSAPPLYINFOVO + nlsApplyInfoVO.getExecuteTime()),
                    JSON.toJSONString(nlsApplyInfoVO).getBytes("UTF-8"));
            message.setDelayTimeLevel(delayTimes(nlsApplyInfoVO.getExecuteTime()));
            producerService.sendMsg(message);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            logger.error("用信申请流水号【" + nlsApplyInfoVO.getApplySeq() + "】执行放款补偿任务时，发送mq出现异常!!!");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("用信申请流水号【" + nlsApplyInfoVO.getApplySeq() + "】执行放款补偿任务时，更新补偿任务执行次数失败!!!");
        }
    }

    @Override
    protected NlsApplyInfoVO convertToJavaBean(String body) {
        return JSONObject.parseObject(body, NlsApplyInfoVO.class);
    }


    private NlsApplyInfoVO updateNlsApplyInfoFailureStatus(NlsApplyInfoVO nlsApplyInfoVO, String loanNo, String distrNo) {
        nlsApplyInfoVO.setNlsApplyState(NLS_APPLY_STATE_03);
        nlsApplyInfoVO.setFlowStatus(FLOW_STATUS_7);
        //设置放款状态信息为失败
        nlsApplyInfoVO.setDnSts(BaseConstant.DN_STS_0);
        // 更新贷款号和发放号
        nlsApplyInfoVO.setLoanNo(loanNo);
        nlsApplyInfoVO.setDistrNo(distrNo);
        return nlsApplyInfoVO;
    }

    private NlsApplyInfoVO updateNlsApplyInfoSuccessStatus(NlsApplyInfoVO nlsApplyInfoVO, String loanNo, String distrNo) {
        nlsApplyInfoVO.setRefuseCause(StringUtils.EMPTY);
        nlsApplyInfoVO.setFlowStatus(FLOW_STATUS_6);
        // 设置放款状态信息为成功
        nlsApplyInfoVO.setDnSts(BaseConstant.DN_STS_6);
        // 更新贷款号和发放号
        nlsApplyInfoVO.setLoanNo(loanNo);
        nlsApplyInfoVO.setDistrNo(distrNo);
        nlsApplyInfoVO.setRefuseCause(StringUtils.EMPTY);
        //更新执行次数
        nlsApplyInfoVO.setExecuteTime(0);
        return nlsApplyInfoVO;
    }

    /**
     * 贷款开立服务查询接口
     */
    @Autowired
    @Qualifier("psdLoanReleaseService")
    private PsdLoanReleaseServiceImpl psdLoanReleaseService;

    /**
     * mq
     */
    @Autowired
    @Qualifier("producerService")
    private MQProducerMessageClient producerService;

    /**
     * 用信服务
     */
    @Autowired
    @Qualifier("nlsApplyInfoService")
    private NlsApplyInfoService nlsApplyInfoService;

    /**
     * 额度信息服务
     */
    @Autowired
    @Qualifier("lmtPrdContService")
    private LmtPrdContService lmtPrdContService;
    /**
     * 同步任务
     */
    @Autowired
    @Qualifier("psdSyncLoanInfoService")
    private PsdSyncLoanInfoServiceImpl syncLoanInfoHsdService;

}
